#ifndef INSTRUCCION_H
#define INSTRUCCION_H

#include "global.h"

enum TipoInstruccion {
	// Grupo de transferencia de datos
	MOV,
	MVI,
	LXI,
	LDA,
	STA,
	LHLD,
	SHLD,
	LDAX,
	STAX,
	XCHG,
	// Grupo aritmetico
	ADD,
	ADI,
	ADC,
	ACI,
	SUB,
	SUI,
	SBB,
	SBI,
	INR,
	DCR,
	INX,
	DCX,
	DAD,
	DAA,
	// Grupo logico
	ANA,
	ANI,
	XRA,
	XRI,
	ORA,
	ORI,
	CMP,
	CPI,
	RLC,
	RRC,
	RAL,
	RAR,
	CMA,
	CMC,
	STC,
	// Grupo de ramificacion
	JMP,
	JCOND,
	CALL,
	CCOND,
	RET,
	RCOND,
	RST,
	PCHL,
	// Grupo de control de stack, maquina y E/S
	PUSH,
	POP,
	XTHL,
	SPHL,
	IN,
	OUT,
	EI,
	DI,
	HLT,
	NOP,
	RIM,
	SIM
};

enum Condicion {
	CONDICION_C,
	CONDICION_NC,
	CONDICION_Z,
	CONDICION_NZ,
	CONDICION_P,
	CONDICION_M,
	CONDICION_PE,
	CONDICION_PO
};

class Instruccion {
	public:
		// Modificadores
		void setLargo(int largo);
		void setTipo(TipoInstruccion tipo);
		void setRegistro(Registro registro);
		void setOrigen(Registro origen);
		void setDestino(Registro destino);
		void setParDeRegistros(ParDeRegistros par);
		void setValorInmediato8(byte valor8);
		void setValorInmediato16(word valor16);
		void setCondicion(Condicion condicion);
		void setPuerto(Puerto puerto);
		// Accesores
		int getLargo() const;
		TipoInstruccion getTipo() const;
		Registro getRegistro() const;
		Registro getOrigen() const;
		Registro getDestino() const;
		ParDeRegistros getParDeRegistros() const;
		byte getValorInmediato8() const;
		word getValorInmediato16() const;
		Condicion getCondicion() const;
		Puerto getPuerto() const;
	private:
		int largo_;
		TipoInstruccion tipo_;
		Registro registro_, origen_, destino_;
		ParDeRegistros par_;
		byte valor_inmediato_8_;
		word valor_inmediato_16_;
		Condicion condicion_;
		Puerto puerto_;
};
#endif
